//////
///// GarryWare Prime
//// Server Ware Engine
///

local WAREMASTER = {}
local WM = WAREMASTER

//WAREMASTER.DATA = {}

function WareMaster()
	return WAREMASTER
	
end

function WM:Initialize()
	self.iNotEnoughTimeCap		= 20 -- Time left < this => End of game. seconds
	self.iDefaultAnnouncerID	= 1
	
end

function WM:PrepareNewWare()
	self.bCanFirstWinner		= false
	self.bCanFirstLoser			= false
	self.bHasFirstWinner		= false
	self.bHasFirstLoser			= false
	self.iPhaseCurrent			= 1
	self.iNextLength			= 0
	
	for k,v in pairs( player.GetAll() ) do 
		v:SetLockedInternal(false)
		v:RemoveFirst()
		v:StripWeapons()
		
	end
	
end

----

function WM:GetPlayers()
	return team.GetPlayers( TEAM_HUMANS )
	
end

function WM:GetTimescale()
	return GetConVarNumber("host_timescale")
	
end

----

function WM:SetCanFirstWinner( bCan )
	self.bCanFirstWinner = bCan
	
end

function WM:SetCanFirstLoser( bCan )
	self.bCanFirstLoser = bCan
	
end

function WM:CanFirstWinner()
	return self.bCanFirstWinner
	
end

function WM:CanFirstLoser()
	return self.bCanFirstLoser
	
end

function WM:HasFirstWinner()
	return self.bHasFirstWinner
	
end

function WM:HasFirstLoser()
	return self.bHasFirstLoser
	
end

function WM:DeclareFirstWinner(ply)
	if not self:CanFirstWinner() then return false end
	if not ValidEntity(ply) or not py:IsPlayer() then return false end
	if not ply:IsWarePlayer() then return false end
	
	if self:HasFirstWinner() then return false end
	
	// TODO: Manage ply
	self.bHasFirstWinner = true
	
	ply:ApplyFirst( )
	
	return true
	
end

function WM:DeclareFirstLoser(ply)
	if not self:CanFirstLoser() then return false end
	if not ValidEntity(ply) or not py:IsPlayer() then return false end
	if self:HasFirstLoser() then return false end
	if not ply:IsWarePlayer() then return false end
	
	if not ply:IsWarePlayer() then return end
	
	// TODO: Manage ply
	self.bHasFirstLoser = true
	
	ply:ApplyFirst( )
	
	return true
	
end

----

function WM:EmitSound( obj, sSound, iVolume, iPitch )	
	local iPitchScaled = self:GetTimescale() * (iPitch or 100)
	if iPitchScaled > 255 then iPitchScaled = 255 end
	
	if ValidEntity( obj ) then
		obj:EmitSound( sSound, iVolume, iPitchScaled )
		
	elseif IsVector( obj ) then
		WorldSound( sSound, iVolume, iPitchScaled )
		
	else
		self:StreamSound( nil, sSound, iVolume, iPitchScaled )
		
	end
	
end

----
////

function WN:SetEveryoneWin( isAchieved_nilIfUnknown )
	self:SetEveryoneStatus(true)
	
end

function WN:SetEveryoneLose( isAchieved_nilIfUnknown )
	self:SetEveryoneStatus(false)
	
end

function WN:SetEveryoneUnknown( isAchieved_nilIfUnknown )
	self:SetEveryoneStatus(nil)
	
end


function WN:SetEveryoneStatus( isAchieved_nilIfUnknown )
	-- nil as an achieved status in which players don't know if they win or lose
	
	for k,v in pairs(player.GetAll()) do 
		v:SetAchievedInternal( ((isAchievedNilIfMystery == nil) and -1) or ((isAchievedNilIfMystery) and 1) or 0 )
		
	end
	
end

function WM:PickRandomGame()
	self:PrepareNewWare()
	
	self.oMinigame = ware_mod.CreateInstance(self.NextGameName)
	
	-- Ware is initialized
	if self.oMinigame and self.oMinigame.Initialize and self.oMinigame.StartAction then
		self.oMinigame:Initialize()
		
	else
		self.oMinigame = ware_mod.CreateInstance("_empty")
		self:SetWareWindupAndLength(0, 3)
		
		self:SetPlayersInitialStatus( false )
		self:DrawInstructions( "Error with minigame \""..self.NextGameName.."\"." )
		
	end
	self.NextgameEnd = CurTime() + self.Windup + self.WareLen
	
	self.NumberOfWaresPlayed = self.NumberOfWaresPlayed + 1
	
	if not self.WareOverrideAnnouncer then
		self.WareOverrideAnnouncer = self.DefaultAnnouncerID or math.random(1, #self.WASND.BITBL_TimeLeft )
	end
	
	local iLoopToPlay = ( (self.Windup + self.WareLen) >= 10 ) and 2 or 1
	
	-- Send info about ware
	local rp = RecipientFilter()
	rp:AddAllPlayers()
	umsg.Start("NextGameTimes", rp)
		umsg.Float( CurTime() + self.Windup )
		umsg.Float( self.NextgameEnd )
		umsg.Float( self.Windup )
		umsg.Float( self.WareLen )
		umsg.Bool( self.WareShouldNotAnnounce )
		umsg.Bool( true )
		umsg.Char( 1 )
		umsg.Char( math.random(1, #self.tSOUND.TBL_GlobalWareningNew ) )
		umsg.Char( self.WareOverrideAnnouncer )
		umsg.Char( iLoopToPlay )
	umsg.End()
	self.WareShouldNotAnnounce = false
	
end

function WM:AppendEntToBin( weaponSim )
	// TODO
	
end
